package com.zhangshuo.common.shiro;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.pam.UnsupportedTokenException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.codec.Hex;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by Administrator on 2017/6/2 0002.
 * 自定义的realm
 */
public class MyDbRealm extends AuthorizingRealm {

    private MyDbRealm(){}
    public MyDbRealm(CacheManager cacheManager, CredentialsMatcher matcher) {
        super(cacheManager, matcher);
    }

    Logger logger = LoggerFactory.getLogger(MyDbRealm.class);
    /**
     * 授权
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
         ShiroUser user = (ShiroUser) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.addRole("ADMIN");
        authorizationInfo.addStringPermission("/redis/testCache");
        authorizationInfo.addStringPermission("/redis/testSession");
        authorizationInfo.addStringPermission("/redis/testSessionGet/**");
        return authorizationInfo;
    }

    /**
     * 用户登陆验证
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        if (! (token instanceof UsernamePasswordToken)){
            throw new UnsupportedTokenException("token类型不支持");
        }
        String username = ((UsernamePasswordToken)token).getUsername();

        ShiroUser shiroUser = new ShiroUser();
        shiroUser.setUserName(username);
        shiroUser.setPassword("123456");
        //在这里可以设置salt的值，在密码匹配器里面，会根据这里设置的salt值就加密token中的密码，然后再与这里提供的密码比对
        //默认以HEX进行编码
        //在这里shiroUser是princal，里面保存了大部分信息，主要用来保存用户名/权限列表/角色列表，后通可以通过SecurityUtils.getSubject().getPrical()
        //来获取用户名等相关信息，第二个参数为密码，为从数据库查询出来的加密过的密码
        return new SimpleAuthenticationInfo(shiroUser,new Md5Hash(shiroUser.getPassword()).toHex(),getName());
    }

    /**
     * 退出登陆时清空缓存
     * @param principals
     */
    @Override
    public void onLogout(PrincipalCollection principals) {
        ShiroUser shiroUser = (ShiroUser) principals.getPrimaryPrincipal();
        SimplePrincipalCollection simplePrincipalCollection = new SimplePrincipalCollection();
        simplePrincipalCollection.add(shiroUser.getUserName(),getName());
        super.clearCachedAuthorizationInfo(simplePrincipalCollection);
    }
}
